package com.bor.gb.db.services;

import com.bor.gb.core.exception.PlaceNotFoundException;
import com.bor.gb.core.repo.DataService;
import com.bor.gb.db.domain.Guide;
import com.bor.gb.db.domain.Place;
import com.bor.gb.db.domain.PlaceNote;
import com.bor.gb.db.domain.User;
import com.bor.gb.db.repositories.GuideRepository;
import com.bor.gb.db.repositories.PlaceRepository;
import com.bor.gb.db.repositories.UserRepository;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Nonnull;
import java.util.List;
import java.util.Set;

/**
 * Created by bor on 11/6/14.
 */
@Component
public class GuideService extends DataService<Guide> {

    private static final Log log = LogFactory.getLog(GuideService.class);

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private PlaceRepository placeRepository;

    @Autowired
    private PlaceService placeService;

    @Autowired
    private GuideRepository guideRepository;


    public Guide createGuide(String name, String userId, String placeId, Set<PlaceNote> contents, String description) {

        Place place = placeService.getOrCreate(placeId);
        User user = userRepository.getById(userId);

        Guide guide = new Guide();
        // todo validators
        guide.setName(name);
        guide.setEntries(contents);
        guide.setUrl(generateUrl(place, user, name));
        guide.setDescription(description);
        guide.setPlace(place);

        guide = save(guide);
        return guide;
    }


    @Nonnull
    private String generateUrl(@Nonnull Place place, @Nonnull User user, String name) {
        String tryUrl = place.getCountry() + "_" + place.getTown() + "_" + name;
        if (guideRepository.isExistByUrl(tryUrl))
            tryUrl += "_by_" + user.getUsername();
        return tryUrl;
    }


    @Nonnull
    public List<Guide> getGuides(String placeId) {
        Place place = placeRepository.findByGooglePlaceId(placeId);
        if (place == null) throw new PlaceNotFoundException();
        List<Guide> guides = guideRepository.findGuidesByPlace(place);
        return guides;
    }


    public Guide plus(String guideId, String userId, boolean like) {
        Guide guide = guideRepository.getById(guideId);
        User user = userRepository.getById(userId);
        log.debug("Guide id: " + guideId + ", name: " + guide.getName() + ". Status Plus(" + like + ") by user " + user.getEmail());

        List<String> pluses = guide.getPlusIds();
        if (pluses.contains(userId) && like) {
            // nothing to change
            return guide;
        } else {
            if (like) {
                guide.getPlusIds().add(userId);
                guide.getMinusIds().remove(userId);
            } else {
                guide.getPlusIds().remove(userId);
            }
            guide = save(guide);

            return guide;
        }
    }


    public Guide minus(String guideId, String userId, boolean status) {
        Guide guide = guideRepository.getById(guideId);
        User user = userRepository.getById(userId);
        log.debug("Guide id: " + guideId + ", name: " + guide.getName() + ". Status Minus(" + status + ") by user " + user.getEmail());

        List<String> minuses = guide.getMinusIds();
        if (minuses.contains(userId) && status) {
            // nothing to change
            return null;
        } else {
            if (status) {
                guide.getMinusIds().add(userId);
                guide.getPlusIds().remove(userId);
            } else {
                guide.getMinusIds().remove(userId);
            }
            guide = save(guide);

            return guide;
        }
    }

/*    public void minus(String guideId, String userId, boolean minus) {

        Guide guide  = getGuide(guideId);
        assert guide != null ;

        User user = userRepository.findById(userId);

        List<String> guides = guide.getPlusIds();

        boolean current = guides.contains(user.getEmail());
        if(minus && current) {
            throw new AlreadyDislikedException();

        }
        else {
            guide.getPlusIds().remove(user.getEmail());
            guide.getPlusIds().add(user.getEmail());
            guide.getMinusIds().remove(user.getEmail());
        }

        guideRepository.save(guide);

    }*/

}
